﻿using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using IWshRuntimeLibrary;

namespace StartAPP
{
    [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
    public class SECURITY_ATTRIBUTES
    {
        public int nLength;
        public string lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFO
    {
        public int cb;
        public string lpReserved;
        public string lpDesktop;
        public int lpTitle;
        public int dwX;
        public int dwY;
        public int dwXSize;
        public int dwYSize;
        public int dwXCountChars;
        public int dwYCountChars;
        public int dwFillAttribute;
        public int dwFlags;
        public int wShowWindow;
        public int cbReserved2;
        public byte lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    /// <summary>
    /// 启动器
    /// </summary>
    class Program
    {
        [DllImport("Kernel32.dll ", EntryPoint = "CreateProcess", CharSet = CharSet.Unicode)]
        public static extern bool CreateProcess(
           StringBuilder lpApplicationName, StringBuilder lpCommandLine,
           SECURITY_ATTRIBUTES lpProcessAttributes,
           SECURITY_ATTRIBUTES lpThreadAttributes,
            bool bInheritHandles,
            int dwCreationFlags,
           StringBuilder lpEnvironment,
           StringBuilder lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation
           );

        /// <summary>
        /// 检测一个系统核心对象(线程，事件，信号)的信号状态
        /// 当对象执行时间超过dwMilliseconds就返回，否则就一直等待对象返回信号
        /// </summary>
        /// <param name="hHandle"></param>
        /// <param name="dwMilliseconds"></param>
        /// <returns></returns>
        [DllImport("Kernel32.dll")]
        public static extern uint WaitForSingleObject(System.IntPtr hHandle, uint dwMilliseconds);

        /// <summary>
        /// 关闭一个内核对象,释放对象占有的系统资源。
        /// 其中包括文件、文件映射、进程、线程、安全和同步对象等
        /// </summary>
        /// <param name="hObject"></param>
        /// <returns></returns>
        [DllImport("Kernel32.dll")]
        public static extern bool CloseHandle(System.IntPtr hObject);

        /// <summary>
        /// 获取一个已中断进程的退出代码,非零表示成功，零表示失败。
        /// 参数hProcess，想获取退出代码的一个进程的句柄，参数lpExitCode，用于装载进程退出代码的一个长整数变量。
        /// </summary>
        /// <param name="hProcess"></param>
        /// <param name="lpExitCode"></param>
        /// <returns></returns>
        [DllImport("Kernel32.dll")]
        static extern bool GetExitCodeProcess(System.IntPtr hProcess, ref uint lpExitCode);

        /// <summary>
        /// 查找窗体句柄
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName">窗体名字</param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Unicode)]
        extern static int FindWindowByName(string lpClassName, string lpWindowName);

        /// <summary>
        /// 设置窗体标题
        /// </summary>
        /// <param name="windowPtr">窗体句柄id</param>
        /// <param name="lpString">新标题名称</param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "SetWindowText", CharSet = CharSet.Unicode)]
        extern static int SetWindowText(int windowPtr, string lpString);



        //是否已经找到窗体
        static bool hasFindWindow = false;

        //默认应用名称
        static string defaultAppname = "决战传奇";

        //默认应用名配置文件路径
        const string defaultAppnameConfigPath = @"DefaultgameName.txt";

        static void Main(string[] args)
        {
            string productName = Process.GetCurrentProcess().MainModule.FileName;//正式
            //string productName = @"C:\Users\wangdoudou\Desktop\BuildTools\Build_Win32\传奇人生\传奇人生.exe";//测试
            Console.WriteLine("应用名称：" + productName);

            string dllName = productName.Replace("exe", "dll", StringComparison.OrdinalIgnoreCase);
            Console.WriteLine("DLL名称：" + dllName);

            string tempNamePath = AppDomain.CurrentDomain.BaseDirectory + defaultAppnameConfigPath;//正式
            //string tempNamePath = @"C:\Users\wangdoudou\Desktop\BuildTools\Build_Win32\StartTools\" + defaultAppnameConfigPath;//测试
            if (System.IO.File.Exists(tempNamePath))
            {
                defaultAppname = LoadDefaultGameName(tempNamePath);
            }


            string strFileName = System.IO.Path.GetFileName(productName).Replace(".exe", "");
            Console.WriteLine("exe名称：" + strFileName);

            if (!productName.ToLower().Contains("appdata") && !productName.ToLower().Contains("local"))
            {
                //创建桌面快捷方式
                if (CreateShortcutOnDesktop(strFileName, productName))
                {
                    Console.WriteLine("创建桌面快捷方式成功：" + strFileName);
                }
                else
                {
                    Console.WriteLine("创建桌面快捷方式失败：" + strFileName);
                }
            }
           

            //运行dll2
            STARTUPINFO sInfo = new STARTUPINFO();
            PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();

            if (!CreateProcess(new StringBuilder(dllName), new StringBuilder(dllName), null, null, false, 0, null, null, ref sInfo, ref pInfo))
            {
                Console.WriteLine("创建运行dll进程失败");
                return;
            }
            else
            {
                Console.WriteLine("创建运行dll进程成功");
            }

            //修改窗体名称
            while (!hasFindWindow)
            {
                ChangeWindowTitle(defaultAppname, strFileName);
            }

            uint u = 0;
            WaitForSingleObject(pInfo.hProcess, int.MaxValue);
            GetExitCodeProcess(pInfo.hProcess, ref u);
            CloseHandle(pInfo.hProcess);
            CloseHandle(pInfo.hThread);
        }

        /// <summary>
        /// 修改窗体标题名称
        /// </summary>
        /// <param name="titleName">原窗体名称</param>
        /// <param name="changeName">要修改为的窗体名称</param>
        public static void ChangeWindowTitle(string titleName, string changeName)
        {
            if (string.IsNullOrEmpty(titleName))
            {
                return;
            }

            //查找窗体
            int intPtr = FindWindowByName(null, titleName);

            //窗体存在
            if (intPtr != 0)
            {
                hasFindWindow = true;
                Console.WriteLine("窗体已找到!");
                if (SetWindowText(intPtr, changeName) != 0)
                {
                    Console.WriteLine("设置标题成功!");
                }
                else
                {
                    Console.WriteLine("设置标题失败!");
                }
            }
        }

        /// <summary>
        /// 加载默认应用名
        /// </summary>
        /// <param name="filePath">路径</param>
        /// <returns></returns>
        public static string LoadDefaultGameName(string filePath)
        {
            string tempName = "";

            string[] lines = System.IO.File.ReadAllLines(filePath, Encoding.UTF8);
            if (lines == null || lines.Length == 0)
            {
                return tempName;
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i].Trim();
                if (string.IsNullOrEmpty(line) || line.StartsWith("#", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (line.Contains("=", StringComparison.OrdinalIgnoreCase))
                {
                    string[] arr = line.Split("=");
                    if (arr == null || arr.Length == 0)
                    {
                        continue;
                    }

                    if (arr[0].Equals("DefaultgameName", StringComparison.OrdinalIgnoreCase))
                    {
                        if (arr.Length == 2)
                        {
                            tempName = arr[1];
                            break;
                        }
                    }
                }
            }

            return tempName;
        }

        /// <summary>
        /// 创建桌面快捷方式
        /// </summary>
        /// <param name="fileName">文件的名称</param>
        /// <param name="exePath">EXE的路径</param>
        /// <returns>成功或失败</returns>
        public static bool CreateShortcutOnDesktop(string fileName, string exePath)
        {
            //添加引用 (com->Windows Script Host Object Model)，using IWshRuntimeLibrary;
            String shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".lnk");
            try
            {
                if (!System.IO.File.Exists(shortcutPath))
                {
                    IWshShell shell = new WshShell();
                    //确定是否已经创建的快捷键被改名了
                    foreach (var item in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "*.lnk"))
                    {
                        WshShortcut tempShortcut = (WshShortcut)shell.CreateShortcut(item);
                        if (tempShortcut.TargetPath == exePath)
                        {
                            return false;
                        }
                    }
                    WshShortcut shortcut = (WshShortcut)shell.CreateShortcut(shortcutPath);
                    shortcut.TargetPath = exePath;
                    shortcut.Arguments = "";// 参数  
                    shortcut.Description = fileName;
                    shortcut.WorkingDirectory = Environment.CurrentDirectory;//程序所在文件夹，在快捷方式图标点击右键可以看到此属性  
                    shortcut.IconLocation = exePath;//图标，该图标是应用程序的资源文件  
                    shortcut.WindowStyle = 1;
                    shortcut.Save();

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}